<?php
/************************
 *  Codenova.pl Project
 *  Created by: Kamil Mrzygłód
 *
 *  (c) 2013 by Codenova.pl
 *  All Right Reserved
 ***********************/

namespace Gotcha\App\Extensions;

// Gotcha HTML extension

use Gotcha\App\Types\Bool;
use Gotcha\App\Types\String;
use Gotcha\App\Types\Arrays;

/** @noinspection PhpInconsistentReturnPointsInspection */
class HtmlExtension {
    // ActionLink()
    /** @noinspection PhpInconsistentReturnPointsInspection */
    protected function ActionLink1String2String(String $action, String $controller) {
        // Function renders a HTML <a> link basing on given parameters.
        // This overload returns plain link, without possibility to add
        // optional attributes
        foreach(FileSystemExtension::returnRoutesValues() as $routeKey => $route) {
            if($route['controller'] == $controller) {
                if($route['action'] == $action) {
                    // We found controller and its action.
                    // Notice that this overload returns FIRST
                    // combination that matches given pattern.
                    // If there is more than one combination in
                    // routing repository, it can return wrong
                    // result.
                    $result = new String(sprintf('<!--suppress HtmlUnknownTarget --><a href="%s">%s</a>', GOTCHA_BASE_PATH.$routeKey, $action));
                    return $result;
                }
            }
        }

        // If we get that far, throw an error
        // cause there is no registered action/controller
        ErrorsExtension::throwErrorAndSaveLog(new String('NO_REGISTERED_ACTION_CONTROLLER_FOUND'), new Arrays(array($action, $controller)));
    }

    /** @noinspection PhpInconsistentReturnPointsInspection */
    protected function ActionLink1String2String3String(String $action, String $controller, String $linkText) {
        // This function is similar to ActionLink1String2String()
        // but additionally adds possibility to change link text
        foreach(FileSystemExtension::returnRoutesValues() as $routeKey => $route) {
            if($route['controller'] == $controller) {
                if($route['action'] == $action) {
                    $result = new String(sprintf('<!--suppress HtmlUnknownTarget --><a href="%s">%s</a>', GOTCHA_BASE_PATH.$routeKey, $linkText));
                    return $result;
                }
            }
        }

        // If we get that far, throw an error
        // cause there is no registered action/controller
        ErrorsExtension::throwErrorAndSaveLog(new String('NO_REGISTERED_ACTION_CONTROLLER_FOUND'), new Arrays(array($action, $controller)));
    }

    /** @noinspection PhpInconsistentReturnPointsInspection */
    protected function ActionLink1String2String3String4String(String $action, String $controller, String $module, String $linkText) {
        // Function is similar to ActionLink1String2String3String()
        // but accepts additional parameter String $module, which
        // can be helpful if there are identically named
        // actions/controllers
        foreach(FileSystemExtension::returnRoutesValues() as $routeKey => $route) {
            if($route['module'] == $module) {
                if($route['controller'] == $controller) {
                    if($route['action'] == $action) {
                        $result = new String(sprintf('<!--suppress HtmlUnknownTarget --><a href="%s">%s</a>', GOTCHA_BASE_PATH.$routeKey, $linkText));
                        return $result;
                    }
                }
            }
        }

        // If we get that far, throw an error
        // cause there is no registered action/controller
        ErrorsExtension::throwErrorAndSaveLog(new String('NO_REGISTERED_ACTION_CONTROLLER_MODULE_FOUND'), new Arrays(array($action, $controller, $module)));
    }

    /** @noinspection PhpInconsistentReturnPointsInspection */
    protected function ActionLink1String2String3String4String5Array(String $action, String $controller, String $module, String $linkText, Arrays $htmlAttributes) {
        // Function is similar to ActionLink1String2String3String4String()
        // but additionally accepts argument Arrays $htmlAttributes which
        // enables user to pass some attributes to be build with a link
        foreach(FileSystemExtension::returnRoutesValues() as $routeKey => $route) {
            if($route['module'] == $module) {
                if($route['controller'] == $controller) {
                    if($route['action'] == $action) {
                        // Build HTML attributes
                        $attributes = $this->setHtmlAttributes($htmlAttributes);

                        $result = new String(sprintf('<a %s href="%s">%s</a>', $attributes, GOTCHA_BASE_PATH.$routeKey, $linkText));
                        return $result;
                    }
                }
            }
        }

        // If we get that far, throw an error
        // cause there is no registered action/controller
        ErrorsExtension::throwErrorAndSaveLog(new String('NO_REGISTERED_ACTION_CONTROLLER_MODULE_FOUND'), new Arrays(array($action, $controller, $module)));
    }

    // HtmlLabel()
    protected function HtmlLabel1String2String(String $id, String $labelText) {
        // Function return a HTML label with given ID and
        // text to display
        return new String(sprintf('<label for="%s">%s</label>', $id, $labelText));
    }

    protected function HtmlLabel1String2String3Array(String $id, String $labelText, Arrays $htmlAttributes) {
        // Function is similar to HtmlLabel1String2String()
        // but additionally sets HTML attributes for a label

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<label %s for="%s">%s</label>', $attributes, $id, $labelText));
    }

    // HtmlTextBox()
    protected function HtmlTextBox1String(String $id) {
        // Function return a HTML textbox where its
        // id is the same as its name
        return new String(sprintf('<input name="%s" id="%s" />', $id, $id));
    }

    protected function HtmlTextBox1String2String(String $id, String $name) {
        // Function return a HTML textbox with given
        // name and id
        return new String(sprintf('<input name="%s" id="%s" />', $id, $name));
    }

    protected function HtmlTextBox1String2Array(String $id, Arrays $htmlAttributes) {
        // Function return a HTML textbox where its
        // id is the same as its name but additionally
        // sets HTML attributes

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<input %s name="%s" id="%s" />', $attributes, $id, $id));
    }

    protected function HtmlTextBox1String2String3Array(String $id, String $name, Arrays $htmlAttributes) {
        // Function is similar to TextBox1String2String
        // but additionally sets HTML attributes

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<input %s name="%s" id="%s" />', $attributes, $name, $id));
    }

    // HtmlRadio()
    protected function HtmlRadio1String2String3String(String $id, String $name, String $value) {
        // Build basic HTML radio input element
        return new String(sprintf('<input type="radio" id="%s" name="%s" value="%s">', $id, $name, $value));
    }

    protected function HtmlRadio1String2String3String4Array(String $id, String $name, String $value, Arrays $htmlAttributes) {
        // Method is similar to previous but additionally
        // builds HTML attributes into a tag

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<input %s type="radio" id="%s" name="%s" value="%s">', $attributes, $id, $name, $value));
    }

    // HtmlCheckbox()
    protected function HtmlCheckbox1String2String3String(String $id, String $name, String $value) {
        // Build basic HTML checkbox input element
        return new String(sprintf('<input type="checkbox" id="%s" name="%s" value="%s">', $id, $name, $value));
    }

    protected function HtmlCheckbox1String2String3String4Array(String $id, String $name, String $value, Arrays $htmlAttributes) {
        // Method is similar to previous but additionally
        // builds HTML attributes into a tag

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<input %s type="checkbox" id="%s" name="%s" value="%s">', $attributes, $id, $name, $value));
    }

    // HtmlBeginForm()
    protected function HtmlBeginForm1String2String(String $action, String $method) {
        // Method builds basic HTML form with specified
        // $action and $method
        return new String(sprintf('<!--suppress HtmlUnknownTarget --><form method="%s" action="%s">', $method, $action));
    }

    protected function HtmlBeginForm1String2String3Array(String $action, String $method, Arrays $htmlAttributes) {
        // Method is similar to previous one but additionally
        // builds HTML attributes

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);
        return new String(sprintf('<form %s method="%s" action="%s">', $attributes, $method, $action));
    }

    protected function HtmlBeginForm1String2String3Array4Bool(String $action, String $method, Arrays $htmlAttributes, Bool $requestValidationToken) {
        // Method is similar to HtmlBeginForm1String2String3Array()
        // but additionally offers a possibility to add a
        // validation token
        $validationField = new String('');

        // Build HTML attributes
        $attributes = $this->setHtmlAttributes($htmlAttributes);

        // Should we generate validation token?
        if($requestValidationToken) {
            $validationToken = new SecurityExtension();
            $validationField = sprintf('<input type="hidden" name="_requestValidationToken" id="_requestValidationToken" value="%s">', $validationToken->returnFormValidationToken());
        }
        return new String(sprintf('<form %s method="%s" action="%s">%s', $attributes, $method, $action, $validationField));
    }

    protected function HtmlCloseForm() {
        return '</form>';
    }

    // Internal class methods
    private function setHtmlAttributes(Arrays $htmlAttributes) {
        // Build HTML attributes
        $attributes = new String('');
        foreach($htmlAttributes->array as $attribute => $value) {
            $attributes .= $attribute.'="'.$value.'"';
        }

        return $attributes;
    }
}